import vehicleModel from "@basic/assets/vehicle.models";
import { options } from './options'
import { v4 } from 'uuid'
import Vue from 'vue';

export function render ({ key, props, name, pos }) {
  const obj = {}
  obj[name] = `${props?.province || ''} ${props?.city ? '/' : ''} ${props?.city || ''} ${props?.district ? '/' : ''} ${props?.district || ''}`
  obj[pos] = [props?.provinceCode || null, props?.cityCode || null, props?.districtCode || null]
  obj[key] = props
  return obj
}

export function model ({ model }) {
  return vehicleModel?.value.find(desc => desc.value === model)
}

export function unitDesc ({ unit }) {
  return options.find(desc => desc.value === unit).label
}

export function setArray (array) {
  let newArray = [...new Set(array
    .map(item => item.value))]
    .map(value => {
      return array.find(item => item.value === value)
    });
  return newArray
}

const compareArrays = (arr1, arr2, prop) => {
  if (arr1.length !== arr2.length) {
    return false;
  }
  for (let i = 0; i < arr1.length; i++) {
    if (arr1[i][prop] !== arr2[i][prop]) {
      return false;
    }
  }
  return true;
};

export function reduce ({ data, rows }) {
  const daysEqual = data.days === rows.days
  const prop = 'price'
  const compareArraysEqual = compareArrays(data.pricingList, rows.pricingList, prop)
  if (!daysEqual || !compareArraysEqual) {
    return rows
  }
  // return false
}

export function reducePrice ({ data, rows }) {
  const priceEqual = data.price === rows.price
  if (!priceEqual) {
    return rows
  }
  return false
}

export function removeDuplicates (arr, props) {
  return arr.filter((obj, pos, arr) => {
    return arr.map(mapObj => mapObj[props]).indexOf(obj[props]) === pos;
  })
}

export function EditableIncludes () {
  const EDITABLE = [0, 3, 8]
  return EDITABLE
}

export const columns = [
  {
    prop: 'fromCity',
    label: '起点城市',
    isFromAddress: true
  },
  {
    prop: 'toCity',
    label: '目的城市',
    isToAddress: true
  },
  {
    prop: 'billingUnitDesc',
    label: '计费单位',
  },
  {
    prop: 'days',
    label: '时效（天）'
  }
]

const remarks = [
  {
    prop: 'remarks',
    label: '备注'
  }
]

export const addData = ({ item }) => {
  const { fromAddress, toAddress, pricingList, ...args } = item
  const priceList = pricingList.reduce((acc, { price }, index) => {
    if (!price || !isPriceValid(price)) {
      acc.isPriceTip = '价格必填或错误'
    }
    acc[`price${index}`] = price
    return acc
  }, {})

  // 添加数据
  const row = {
    ...args,
    ...priceList,
    pricingList: pricingList,
    ...render({ props: fromAddress, key: 'fromAddress', name: 'fromCity', pos: 'startCity' }),
    ...render({ props: toAddress, key: 'toAddress', name: 'toCity', pos: 'endCity' }),
    billingUnitDesc: unitDesc({ unit: args.billingUnit }),
    code: v4()
  }
  let rows = Object.assign({}, row)
  return rows
}

export const addColumns = ({ item }) => {
  const { pricingList } = item
  // Create new price columns
  const priceColumns = pricingList.map(({ maxValue, minValue, price }, index) => {
    let isPriceError = null
    if (!price || !isPriceValid(price)) {
      isPriceError = true
    }
    const label = `${minValue}≤X＜${maxValue}`
    return { prop: `price${index}`, label, isPriceError }
  })
  // Filter out existing columns and add new columns
  const newColumns = priceColumns.filter(priceColumn =>
    !columns.some(column => column.prop === priceColumn.prop))
  const column = item.remarks
    ? [...columns.slice(0, -1), ...newColumns, columns.slice(-1)[0], ...remarks]
    : [...columns.slice(0, -1), ...newColumns, columns.slice(-1)[0]]
  return column
}

export const hasSameTemplateRuleId = (data) => {
  const templateRuleIds = new Set();
  for (const { tableData } of data) {
    for (const { templateRuleId } of tableData) {
      if (templateRuleIds.has(templateRuleId)) {
        return true;
      }
      templateRuleIds.add(templateRuleId);
    }
  }
  return false;
};

export const hasSameSingleTemplateRuleId = (tableData) => {
  const templateRuleIds = new Set();
  // for (const { tableData } of data) {
  for (const { templateRuleId } of tableData) {
    if (templateRuleIds.has(templateRuleId)) {
      return true;
    }
    templateRuleIds.add(templateRuleId);
  }
  // }
  return false;
};

export const detailAddressAssignment = ({ rows }) => {
  const { fromAddress, toAddress, startAddress, endAddress, ...args } = rows
  fromAddress.address = startAddress
  toAddress.address = endAddress
  return rows
}

export const detailFormAddressAssignment = ({ rows }) => {
  const { fromAddress, startAddress, ...args } = rows
  fromAddress.address = startAddress
  return rows
}

export const detailToAddressAssignment = ({ rows }) => {
  const { toAddress, endAddress, ...args } = rows
  toAddress.address = endAddress
  return rows
}


// export const interceptRules = (processRules) => {
//   const processTypes = {
//     "deliver": '送货费用',
//     "divide": '零担费用',
//     "load": '装货费用',
//     "pick": '提货费用',
//     "unload": '卸货费用',
//     "whole": '整车费用'
//   };
//   for (let processType in processRules) {
//     const bargainRules = processRules[processType].filter(rule => rule.bargain);
//     if (bargainRules.length > 0) {
//       Vue.prototype.$message({
//         type: "error",
//         message: `${processTypes[processType]}中以下有议价没处理完`
//       });
//       return false;
//     }
//   }
//   return true;
// };


export const CarryTableColumn = [
  {
    prop: 'fromCity',
    label: '起点城市',
    isFromAddress: true
  },
  {
    prop: 'billingUnitDesc',
    label: '计费单位',
  }
]

export const DeliverTableColumn = [
  {
    prop: 'toCity',
    label: '目的城市',
    isToAddress: true
  },
  {
    prop: 'billingUnitDesc',
    label: '计费单位',
  }
]

export const LoadTableColumn = [
  {
    prop: 'billingUnitDesc',
    label: '计费单位',
  }
]

function getAddressList (type, args) {
  const addressProp = type === 'from' ? 'fromAddress' : 'toAddress'
  const cityName = type === 'from' ? 'fromCity' : 'toCity'
  const posName = type === 'from' ? 'startCity' : 'endCity'
  const addressList = render({ props: args?.[addressProp], key: `${addressProp}`, name: cityName, pos: posName })
  return type ? addressList : {}
}

export const addPickData = ({ item, type }) => {
  const { pricingList, ...args } = item
  const priceList = pricingList.reduce((acc, { price }, index) => {
    if (!price || !isPriceValid(price)) {
      acc.isPriceTip = '价格必填或错误'
    }
    acc[`price${index}`] = price
    return acc
  }, {})

  // 添加数据
  const row = {
    ...args,
    ...priceList,
    pricingList: pricingList,
    ...getAddressList(type, args),
    billingUnitDesc: unitDesc({ unit: args.billingUnit }),
    code: v4()
  }
  let rows = Object.assign({}, row)
  return rows
}

export const generateColumns = ({ columns, additionalColumns }) => {
  const mergedColumns = [
    ...columns.slice(0, -1),
    ...additionalColumns.filter(additionalColumn =>
      !columns.some(column => column.prop === additionalColumn.prop)
    ),
    columns.slice(-1)[0]
  ]

  return mergedColumns
}

const pricingPackage = (list) => {
  const listColumns = list.map(({ maxValue, minValue, price }, index) => {
    let isPriceError = null
    if (!price || !isPriceValid(price)) {
      isPriceError = true
    }
    const label = `${minValue}≤X＜${maxValue}`
    return { prop: `price${index}`, label, isPriceError }
  })
  return listColumns
}

export const addDeliverColumns = ({ item }) => {
  const { pricingList } = item
  const priceColumns = pricingPackage(pricingList)
  return generateColumns({ columns: DeliverTableColumn, additionalColumns: priceColumns })
}

export const addCarryColumns = ({ item }) => {
  const { pricingList } = item
  const priceColumns = pricingPackage(pricingList)
  return generateColumns({ columns: CarryTableColumn, additionalColumns: priceColumns })
}

export const addLoadColumns = ({ item }) => {
  const { pricingList } = item
  const priceColumns = pricingPackage(pricingList)
  return generateColumns({ columns: LoadTableColumn, additionalColumns: priceColumns })
}

function isExistingItem ({ tableData, transformRows }) {
  return tableData.find(item => (
    (transformRows?.fromCity === undefined || item.fromCity === transformRows?.fromCity) &&
    (transformRows?.toCity === undefined || item.toCity === transformRows?.toCity) &&
    (transformRows?.billingUnit === undefined || item.billingUnit === transformRows?.billingUnit) &&
    (transformRows?.fromAddress?.address === undefined || transformRows?.fromAddress?.address === '' || item.fromAddress.address === transformRows?.fromAddress?.address) &&
    (transformRows?.toAddress?.address === undefined || transformRows?.toAddress?.address === '' || item.toAddress.address === transformRows?.toAddress?.address) &&
    (transformRows?.vehicleModel === undefined || item.vehicleModel === transformRows?.vehicleModel) &&
    (transformRows?.vehicleLength === undefined || item.vehicleLength === transformRows?.vehicleLength)
  ))
}

export const isExistingCarloadItem = (params, transformRows) =>
  isExistingItem({ ...params, ...transformRows })

export const isExistingVehicleItem = (params, transformRows) =>
  isExistingItem({ ...params, ...transformRows })

export const isExistingCarryItem = (params, transformRows) =>
  isExistingItem({ ...params, ...transformRows })

export const isExistingDeliverItem = (params, transformRows) =>
  isExistingItem({ ...params, ...transformRows })

export const isExistingUnloadItem = (params, transformRows) =>
  isExistingItem({ ...params, ...transformRows })



export function confirmExistingData () {
  return new Promise((resolve, reject) => {
    Vue.prototype.$confirm('列表中已存在该数据，是否覆盖?', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      closeOnClickModal: false,
      showClose: false,
      type: 'warning'
    }).then(() => {
      resolve(true)
      Vue.prototype.$message.success('操作成功')
    }).catch(() => {
      reject(false)
    });
  })
}

export function getAddress (data, address) {
  const province = data.find(item => item.name === address.province)

  let city = null
  let district = null

  if (address?.city) {
    city = province?.children.find(item => item.name === address.city) ?? ''
  } else {
    city = true
  }

  if (address?.district && city instanceof Object) {
    district = city?.children.find(item => item.name === address.district) ?? ''
  } else {
    district = true
  }

  return { province, city, district }
}

const isPriceValid = (price) => {
  const priceStr = price.toString();
  const decimalIndex = priceStr.indexOf('.');
  if (decimalIndex !== -1 && priceStr.substring(decimalIndex + 1).length > 2) {
    return false;
  }
  if (Math.floor(price).toString().length > 7) {
    return false;
  }
  return true;
}

const isValidAll = ({ isDaysError, isFromError, isToError, isBillingUnitError, isPriceError }) =>
  isDaysError || isFromError || isToError || isBillingUnitError || isPriceError;

function checkAddressErrorsHelper (shipment, data) {
  const { province: fromProvince, city: fromCity, district: fromDistrict } = getAddress(data, shipment.fromAddress)
  const { province: toProvince, city: toCity, district: toDistrict } = getAddress(data, shipment.toAddress)

  shipment.isFromError = !fromProvince || !fromCity || !fromDistrict
  shipment.isFromErrorTip = shipment.isFromError ? '起点城市错误' : ''
  shipment.fromAddress.provinceCode = shipment.isFromError ? '' : fromProvince.areaCode
  shipment.fromAddress.cityCode = shipment.isFromError ? '' : fromCity.areaCode
  shipment.fromAddress.districtCode = shipment.isFromError ? '' : fromDistrict.areaCode

  shipment.isToError = !toProvince || !toCity || !toDistrict
  shipment.isToErrorTip = shipment.isToError ? '目的城市错误' : ''
  shipment.toAddress.provinceCode = shipment.isToError ? '' : toProvince.areaCode
  shipment.toAddress.cityCode = shipment.isToError ? '' : toCity.areaCode
  shipment.toAddress.districtCode = shipment.isToError ? '' : toDistrict.areaCode

  shipment.isDaysError = shipment.days > 30 || shipment.days === 0 || !shipment.days
  shipment.isDaysErrorTip = shipment.isDaysError ? '时效天数错误' : ''

  shipment.isBillingUnitError = !shipment?.billingUnit
  shipment.isBillingUnitTip = shipment.isBillingUnitError ? '计费单位必填' : ''

  shipment.pricingList.forEach(item => {
    if (!item?.price || !isPriceValid(item?.price)) {
      shipment.isPriceError = true
      return
    }
    return
  });

  shipment.isError = isValidAll({
    isDaysError: shipment?.isDaysError,
    isFromError: shipment?.isFromError,
    isToError: shipment?.isToError,
    isBillingUnitError: shipment?.isBillingUnitError,
    isPriceError: shipment?.isPriceError
  })
}

// 提货
const isValidFrom = ({ isFromError, isPriceError, isBillingUnitError }) => isFromError || isPriceError || isBillingUnitError;

function checkFromAddressErrorsHelper (shipment, data) {
  const { province: fromProvince, city: fromCity, district: fromDistrict } = getAddress(data, shipment.fromAddress)

  shipment.isFromError = !fromProvince || !fromCity || !fromDistrict
  shipment.isFromErrorTip = shipment.isFromError ? '起点城市错误' : ''
  shipment.fromAddress.provinceCode = shipment.isFromError ? '' : fromProvince.areaCode
  shipment.fromAddress.cityCode = shipment.isFromError ? '' : fromCity.areaCode
  shipment.fromAddress.districtCode = shipment.isFromError ? '' : fromDistrict.areaCode

  shipment.isBillingUnitError = !shipment?.billingUnit
  shipment.isBillingUnitTip = shipment.isBillingUnitError ? '计费单位必填' : ''

  shipment.pricingList.forEach(item => {
    if (!item?.price || !isPriceValid(item?.price)) {
      shipment.isPriceError = true
      return
    }
    return
  });

  shipment.isError = isValidFrom({
    isFromError: shipment?.isFromError,
    isPriceError: shipment?.isPriceError,
    isBillingUnitError: shipment?.isBillingUnitError
  })
}

const isValidTo = ({ isToError, isPriceError, isBillingUnitError }) => isToError || isPriceError || isBillingUnitError;
// 送货
function checkToAddressErrorsHelper (shipment, data) {
  const { province: toProvince, city: toCity, district: toDistrict } = getAddress(data, shipment.toAddress)

  shipment.isToError = !toProvince || !toCity || !toDistrict
  shipment.isToErrorTip = shipment.isToError ? '目的城市错误' : ''
  shipment.toAddress.provinceCode = shipment.isToError ? '' : toProvince.areaCode
  shipment.toAddress.cityCode = shipment.isToError ? '' : toCity.areaCode
  shipment.toAddress.districtCode = shipment.isToError ? '' : toDistrict.areaCode

  shipment.isBillingUnitError = !shipment?.billingUnit
  shipment.isBillingUnitTip = shipment.isBillingUnitError ? '计费单位必填' : ''

  shipment.pricingList.forEach(item => {
    if (!item?.price || !isPriceValid(item?.price)) {
      shipment.isPriceError = true
      return
    }
    return
  });

  shipment.isError = isValidTo({
    isToError: shipment?.isToError,
    isPriceError: shipment?.isPriceError,
    isBillingUnitError: shipment?.isBillingUnitError
  })
}

// 装货

const isValidDress = ({ isPriceError, isBillingUnitError }) => isPriceError || isBillingUnitError;

function checkDressErrorsHelper (shipment) {

  shipment.isBillingUnitError = !shipment?.billingUnit
  shipment.isBillingUnitTip = shipment.isBillingUnitError ? '计费单位必填' : ''

  shipment.pricingList.forEach(item => {
    if (!item?.price || !isPriceValid(item?.price)) {
      shipment.isPriceError = true
      return
    }
    return
  });

  shipment.isError = isValidDress({
    isPriceError: shipment?.isPriceError,
    isBillingUnitError: shipment?.isBillingUnitError
  })
}

// 整车
const isWholeValidAll = ({ isDaysError, isFromError, isToError, isVehicleModelError, isVehicleLengthError, isPriceError }) =>
  isDaysError || isFromError || isToError || isVehicleModelError || isVehicleLengthError || isPriceError;

function checkWholeErrorsHelper (shipment, data) {
  const { province: fromProvince, city: fromCity, district: fromDistrict } = getAddress(data, shipment.fromAddress)
  const { province: toProvince, city: toCity, district: toDistrict } = getAddress(data, shipment.toAddress)

  shipment.isVehicleModelError = !shipment?.vehicleModel
  shipment.isVehicleModelTip = shipment.isVehicleModelError ? '车型必填' : ''

  shipment.isVehicleLengthError = !shipment?.vehicleLength || !shipment?.vehicleWeight || !shipment?.vehicleVolume
  shipment.isVehicleLengthTip = shipment.isVehicleLengthError ? '车辆信息错误' : ''

  shipment.isFromError = !fromProvince || !fromCity || !fromDistrict
  shipment.isFromErrorTip = shipment.isFromError ? '起点城市错误' : ''
  shipment.fromAddress.provinceCode = shipment.isFromError ? '' : fromProvince.areaCode
  shipment.fromAddress.cityCode = shipment.isFromError ? '' : fromCity.areaCode
  shipment.fromAddress.districtCode = shipment.isFromError ? '' : fromDistrict.areaCode

  shipment.isToError = !toProvince || !toCity || !toDistrict
  shipment.isToErrorTip = shipment.isToError ? '目的城市错误' : ''
  shipment.toAddress.provinceCode = shipment.isToError ? '' : toProvince.areaCode
  shipment.toAddress.cityCode = shipment.isToError ? '' : toCity.areaCode
  shipment.toAddress.districtCode = shipment.isToError ? '' : toDistrict.areaCode

  shipment.isPriceError = !shipment.price
  shipment.isPriceTip = shipment.isPriceError ? '价格必填' : ''

  shipment.isDaysError = shipment.days > 30 || shipment.days === 0 || !shipment.days
  shipment.isDaysErrorTip = shipment.isDaysError ? '时效天数错误' : ''

  shipment.isError = isWholeValidAll(
    {
      isDaysError: shipment?.isDaysError,
      isFromError: shipment?.isFromError,
      isToError: shipment?.isToError,
      isVehicleModelError: shipment?.isVehicleModelError,
      isVehicleLengthError: shipment?.isVehicleLengthError,
      isPriceError: shipment?.isPriceError
    })
}


// 整车
export function checkWholeErrors (shipments = [], data) {
  for (const shipment of shipments) {
    checkWholeErrorsHelper(shipment, data)
  }
  return shipments
}

// 零担
export function checkAddressErrors (shipments = [], data) {
  for (const shipment of shipments) {
    checkAddressErrorsHelper(shipment, data)
  }
  return shipments
}

// 提
export function checkFromAddressErrors (shipments = [], data) {
  for (const shipment of shipments) {
    checkFromAddressErrorsHelper(shipment, data)
  }
  return shipments
}

// 送
export function checkToAddressErrors (shipments = [], data) {
  for (const shipment of shipments) {
    checkToAddressErrorsHelper(shipment, data)
  }
  return shipments
}

// 装卸
export function checkLoadErrors (shipments = []) {
  for (const shipment of shipments) {
    checkDressErrorsHelper(shipment)
  }
  return shipments
}

const processTypes = new Map([
  ["deliver", '送货费用'],
  ["divide", '零担费用'],
  ["load", '装货费用'],
  ["pick", '提货费用'],
  ["unload", '卸货费用'],
  ["whole", '整车费用']
]);

export const interceptRules = (processRules, isError) => {
  const tipLetter = isError ? '错误数据' : '议价'
  for (const [processType, rules] of Object.entries(processRules)) {
    const filteredRules = rules.filter(rule => isError ? rule.isError : rule.bargain);
    if (filteredRules.length > 0) {
      Vue.prototype.$message.error(`${processTypes.get(processType)}中有${tipLetter}没处理完`);
      return false;
    }
  }
  return true;
};